﻿using System;

namespace UniRx.Operators
{
	// Token: 0x02000328 RID: 808
	internal class TimeoutObservable<T> : OperatorObservableBase<T>
	{
		// Token: 0x060010D0 RID: 4304 RVA: 0x0004D588 File Offset: 0x0004B988
		public TimeoutObservable(IObservable<T> source, TimeSpan dueTime, IScheduler scheduler) : base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread<T>())
		{
			this.source = source;
			this.dueTime = new TimeSpan?(dueTime);
			this.scheduler = scheduler;
		}

		// Token: 0x060010D1 RID: 4305 RVA: 0x0004D5BE File Offset: 0x0004B9BE
		public TimeoutObservable(IObservable<T> source, DateTimeOffset dueTime, IScheduler scheduler) : base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread<T>())
		{
			this.source = source;
			this.dueTimeDT = new DateTimeOffset?(dueTime);
			this.scheduler = scheduler;
		}

		// Token: 0x060010D2 RID: 4306 RVA: 0x0004D5F4 File Offset: 0x0004B9F4
		protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
		{
			if (this.dueTime != null)
			{
				return new TimeoutObservable<T>.Timeout(this, observer, cancel).Run();
			}
			return new TimeoutObservable<T>.Timeout_(this, observer, cancel).Run();
		}

		// Token: 0x040009E3 RID: 2531
		private readonly IObservable<T> source;

		// Token: 0x040009E4 RID: 2532
		private readonly TimeSpan? dueTime;

		// Token: 0x040009E5 RID: 2533
		private readonly DateTimeOffset? dueTimeDT;

		// Token: 0x040009E6 RID: 2534
		private readonly IScheduler scheduler;

		// Token: 0x02000329 RID: 809
		private class Timeout : OperatorObserverBase<T, T>
		{
			// Token: 0x060010D3 RID: 4307 RVA: 0x0004D62F File Offset: 0x0004BA2F
			public Timeout(TimeoutObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
			{
				this.parent = parent;
			}

			// Token: 0x060010D4 RID: 4308 RVA: 0x0004D64C File Offset: 0x0004BA4C
			public IDisposable Run()
			{
				this.sourceSubscription = new SingleAssignmentDisposable();
				this.timerSubscription = new SerialDisposable();
				this.timerSubscription.Disposable = this.RunTimer(this.objectId);
				//this.sourceSubscription.Disposable = this.parent.source.Subscribe(this);
				return StableCompositeDisposable.Create(this.timerSubscription, this.sourceSubscription);
			}

			// Token: 0x060010D5 RID: 4309 RVA: 0x0004D6B4 File Offset: 0x0004BAB4
			private IDisposable RunTimer(ulong timerId)
			{
				return this.parent.scheduler.Schedule(this.parent.dueTime.Value, delegate()
				{
					object obj = this.gate;
					lock (obj)
					{
						if (this.objectId == timerId)
						{
							this.isTimeout = true;
						}
					}
					if (this.isTimeout)
					{
						try
						{
							this.observer.OnError(new TimeoutException());
						}
						finally
						{
							this.Dispose();
						}
					}
				});
			}

			// Token: 0x060010D6 RID: 4310 RVA: 0x0004D704 File Offset: 0x0004BB04
			public override void OnNext(T value)
			{
				object obj = this.gate;
				bool flag;
				ulong timerId;
				lock (obj)
				{
					flag = this.isTimeout;
					this.objectId += 1UL;
					timerId = this.objectId;
				}
				if (flag)
				{
					return;
				}
				this.timerSubscription.Disposable = Disposable.Empty;
				this.observer.OnNext(value);
				this.timerSubscription.Disposable = this.RunTimer(timerId);
			}

			// Token: 0x060010D7 RID: 4311 RVA: 0x0004D790 File Offset: 0x0004BB90
			public override void OnError(Exception error)
			{
				object obj = this.gate;
				bool flag;
				lock (obj)
				{
					flag = this.isTimeout;
					this.objectId += 1UL;
				}
				if (flag)
				{
					return;
				}
				this.timerSubscription.Dispose();
				try
				{
					this.observer.OnError(error);
				}
				finally
				{
					base.Dispose();
				}
			}

			// Token: 0x060010D8 RID: 4312 RVA: 0x0004D814 File Offset: 0x0004BC14
			public override void OnCompleted()
			{
				object obj = this.gate;
				bool flag;
				lock (obj)
				{
					flag = this.isTimeout;
					this.objectId += 1UL;
				}
				if (flag)
				{
					return;
				}
				this.timerSubscription.Dispose();
				try
				{
					this.observer.OnCompleted();
				}
				finally
				{
					base.Dispose();
				}
			}

			// Token: 0x040009E7 RID: 2535
			private readonly TimeoutObservable<T> parent;

			// Token: 0x040009E8 RID: 2536
			private readonly object gate = new object();

			// Token: 0x040009E9 RID: 2537
			private ulong objectId;

			// Token: 0x040009EA RID: 2538
			private bool isTimeout;

			// Token: 0x040009EB RID: 2539
			private SingleAssignmentDisposable sourceSubscription;

			// Token: 0x040009EC RID: 2540
			private SerialDisposable timerSubscription;
		}

		// Token: 0x0200032A RID: 810
		private class Timeout_ : OperatorObserverBase<T, T>
		{
			// Token: 0x060010D9 RID: 4313 RVA: 0x0004D944 File Offset: 0x0004BD44
			public Timeout_(TimeoutObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
			{
				this.parent = parent;
			}

			// Token: 0x060010DA RID: 4314 RVA: 0x0004D960 File Offset: 0x0004BD60
			public IDisposable Run()
			{
				this.sourceSubscription = new SingleAssignmentDisposable();
				this.timerSubscription = this.parent.scheduler.Schedule(this.parent.dueTimeDT.Value, new Action(this.OnNext));
				//this.sourceSubscription.Disposable = this.parent.source.Subscribe(this);
				return StableCompositeDisposable.Create(this.timerSubscription, this.sourceSubscription);
			}

			// Token: 0x060010DB RID: 4315 RVA: 0x0004D9DC File Offset: 0x0004BDDC
			private void OnNext()
			{
				object obj = this.gate;
				lock (obj)
				{
					if (this.isFinished)
					{
						return;
					}
					this.isFinished = true;
				}
				this.sourceSubscription.Dispose();
				try
				{
					this.observer.OnError(new TimeoutException());
				}
				finally
				{
					base.Dispose();
				}
			}

			// Token: 0x060010DC RID: 4316 RVA: 0x0004DA60 File Offset: 0x0004BE60
			public override void OnNext(T value)
			{
				object obj = this.gate;
				lock (obj)
				{
					if (!this.isFinished)
					{
						this.observer.OnNext(value);
					}
				}
			}

			// Token: 0x060010DD RID: 4317 RVA: 0x0004DAB0 File Offset: 0x0004BEB0
			public override void OnError(Exception error)
			{
				object obj = this.gate;
				lock (obj)
				{
					if (this.isFinished)
					{
						return;
					}
					this.isFinished = true;
					this.timerSubscription.Dispose();
				}
				try
				{
					this.observer.OnError(error);
				}
				finally
				{
					base.Dispose();
				}
			}

			// Token: 0x060010DE RID: 4318 RVA: 0x0004DB30 File Offset: 0x0004BF30
			public override void OnCompleted()
			{
				object obj = this.gate;
				lock (obj)
				{
					if (!this.isFinished)
					{
						this.isFinished = true;
						this.timerSubscription.Dispose();
					}
					try
					{
						this.observer.OnCompleted();
					}
					finally
					{
						base.Dispose();
					}
				}
			}

			// Token: 0x040009ED RID: 2541
			private readonly TimeoutObservable<T> parent;

			// Token: 0x040009EE RID: 2542
			private readonly object gate = new object();

			// Token: 0x040009EF RID: 2543
			private bool isFinished;

			// Token: 0x040009F0 RID: 2544
			private SingleAssignmentDisposable sourceSubscription;

			// Token: 0x040009F1 RID: 2545
			private IDisposable timerSubscription;
		}
	}
}
